package com.general.framework.zzyy.thread01;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * Future 编码实战和相关优缺点分析

 * 优点：
 * Future+线程池异步多线程任务配合，能显著提高程序的运行效率。

 * 缺点:
 * get()阻塞—一旦调用get()方法求结果，一旦调用，非要等到结果才会离开，不管你是否计算完成，如果没有计算完成容易程序堵塞。
 * isDone()轮询—轮询的方式会耗费无谓的cpu资源，而且也不见得能及时得到计算结果，如果想要异步获取结果，通常会以轮询的方式去获取结果，尽量不要阻塞。
 * 结论：
 * Future对于结果的获取不是很友好，只能通过阻塞或轮询的方式得到任务的结果。
 * get()方法可以传入超时时间，如果超时了，就会抛出TimeoutException异常，这样就可以避免一直阻塞等待。那如何解决呢？
 */
public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask, "MyThread1");
        thread.start();

        System.out.println(Thread.currentThread().getName() + ":开始执行其他任务---------");
        while (true) {
            // 轮询判断futureTask业务是否处理完成
            if (futureTask.isDone()) {
                System.out.println(futureTask.get());
                break;
            } else {
                System.out.println("futureTask任务暂时未完成，请等待............");
            }
        }
    }
}

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("futureTask 开始处理任务-------");
        // 处理三秒的业务
        Thread.sleep(3000);
        return "task over";
    }
}